;;;;
;;;; TOP-LEVEL FORMS
;;;;

;(define-method (unparse (d definition))
;  (list 'define
;	(unparse (var d))
;	(unparse (initial-value (var d)))))

(define-method (unparse (cd class-definition))
  (define args (initargs cd))
  (define n (unparse (name cd)))
  (let ((name-field (if args
			(cons n (map unparse args))
			n)))
      `(define-class ,name-field ,(unparse (parent cd))
	 ,@(map unparse (members cd)))))

(define-method (unparse (md member-definition))
  (define v (value md))
  (define k (keywords md))
  (define n (unparse (var md)))
  (if k
      (let ((t (unparse (rtype md))))
	(if (is? v lambda-expression)
	    `(define (,n ,@(map unparse (variables v))) (,@k ,t)
	       ,@(map unparse (body v)))
	    `(define ,n (,@k ,t) ,(unparse v))))
      (if (is? v lambda-expression)
	  `(define (,n ,@(map unparse (variables v)))
	     ,@(map unparse (body v)))
	  `(define ,n ,(unparse v)))))

;;;;
;;;; PRIMITIVE EXPRESSIONS
;;;;

(define-method (unparse (x expression))
  (error "Can't unparse" x))

(define-method (unparse (x constant))
  (define v (value x))
  (if (or (symbol? v)
	  (pair? v))
      (list 'quote v)
      v))

(define-method (unparse (x global-variable))
  (name x))

(define-method (unparse (x local-variable))
  (name x))

;;;;
;;;; COMPOUND EXPRESSIONS
;;;;

(define-method (unparse (t the-expression))
  (define ty (declared-type t))
  (define e (exp t))

  `(the ,(if (is? ty type-class)
	     (name ty)
	     (unparse ty))
	,(unparse e)))

(define-method (unparse (t cast-expression))
  (define ty (declared-type t))
  (define e (exp t))

  `(cast ,(if (is? ty type-class)
	     (name ty)
	     (unparse ty))
	,(unparse e)))

(define-method (unparse (x application))
  (cons (unparse (operator x))
	(map unparse (arguments x))))

(define-method (unparse (x return))
  (list 'return
	(unparse (exp x))))

(define-method (unparse (x set-expression))
  `(set ,(unparse (lvalue x))
	,(unparse (rvalue x))))

(define-method (unparse (x conditional))
  (if (null? (alternative x))
      (seq 'if
	   (unparse (test x))
	   (unparse (consequent x)))
      (seq 'if
	   (unparse (test x))
	   (unparse (consequent x))
	   (unparse (alternative x)))))

(define-method (unparse (x lambda-expression))
  (cons* 'lambda
	 (map unparse (variables x))
	 (map unparse (body x))))

(define-method (unparse (x let-expression))
  (cons* 'let
	 (map (lambda (var)
		(list (name var)
		      (unparse (initial-value var))))
	      (variables x))
	 (map unparse (body x))))

(define-method (unparse (x begin-expression))
  (cons 'begin
	(map unparse (body x))))

(define-method (unparse (w while-expression))
  `(while ,(unparse (test w))
     ,@(map unparse (body w))))

(define-method (unparse (x for-expression))
  (cons* 'do
	 (map (lambda (var iterator)
		(list (name var)
		      (unparse (initial-value var))
		      (unparse iterator)))
	      (variables x)
	      (iterators x))
	 (unparse (test x))
	 (map unparse (body x))))